﻿using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Xml;
using XmlStudio.DataLayer;
using System.ComponentModel;

namespace XmlStudio.Interfaces {
    /// <summary>
    /// Defines operations supported by BigXmlReader.
    /// </summary>
    //[ContractClass(typeof(BigXmlReaderContract))]
    internal interface IBigXmlReader {
        #region Properties
        /// <summary>
        /// Gets the total number of elements and text nodes.
        /// </summary>
        int TotalNodeCount { get; }

        /// <summary>
        /// Gets the value indicating whether the reader is opened.
        /// </summary>
        bool Opened { get; }

        /// <summary>
        /// Gets or sets the path to the read file.
        /// </summary>
        string Path { get; set; }

        /// <summary>
        /// Gets the <see cref="XmlDocument"/> to create nodes.
        /// </summary>
        XmlDocument XmlDocument { get; }
        #endregion

        #region Methods
        /// <summary>
        /// Counts nodes at the specified subtree.
        /// </summary>
        /// <param name="address">Address of the root of the subtree.</param>
        /// <returns>Number of nodes.</returns>
        int CountNodes(int[] address);

        /// <summary>
        /// Gets the document type of the document if exists.
        /// </summary>
        /// <returns><see cref="XmlDocumentType"/> for current document or null if there is no doc type.</returns>
        XmlDocumentType GetDocumentType();

        /// <summary>
        /// Gets the number of child elements of the node with specified address.
        /// </summary>
        /// <param name="address">Address of the element to get the child count of.</param>
        /// <returns>Number of child elements.</returns>
        int GetChildCount(int[] address);

        /// <summary>
        /// Gets the collection of child elements of the node with specified address.
        /// </summary>
        /// <param name="address">Address of the element to get the child elements of.</param>
        /// <param name="range">Filter on child elements, specified which child elements to include in returned collection.</param>
        /// <returns>Collection of BigXmlNodes.</returns>
        IEnumerable<BigXmlNodeInternal> GetChildNodes(int[] address, string range);

        /// <summary>
        /// Gets the collection of child elements of the node with specified address.
        /// </summary>
        /// <param name="address">Address of the element to get the child elements of.</param>
        /// <param name="range">Filter on child elements, specified which child elements to include in returned collection.</param>
        /// <param name="childCount">The child count.</param>
        /// <returns>Collection of BigXmlNodes.</returns>
        IEnumerable<BigXmlNodeInternal> GetChildNodes(int[] address, IEnumerable<int> range, int childCount);

        /// <summary>
        /// Gets all nodes from the specified address to the leaves.
        /// </summary>
        /// <param name="address">Where to start.</param>
        /// <returns>Reference to the root of the loaded subtree.</returns>
        BigXmlNodeInternal GetAllFromAddress(int[] address);

        /// <summary>
        /// Gets the root element of the xml document.
        /// </summary>
        /// <returns>Root element.</returns>
        BigXmlNodeInternal GetRootElement();

        /// <summary>
        /// Checks xml document's well formedness.
        /// </summary>
        void CheckWellFormedness();

        /// <summary>
        /// Writes the child nodes of the specified address to the specified <see cref="XmlWriter"/>.
        /// </summary>
        /// <param name="address">Parent node's address.</param>
        /// <param name="writer"><see cref="XmlWriter"/> where to write child nodes.</param>
        /// <param name="bw">The background worker..</param>
        /// <param name="writeRoot">if set to <c>true</c> [write root].</param>
        void WriteChildNodesFromAddress(int[] address, XmlWriter writer, BackgroundWorker bw, bool writeRoot = false);

        /// <summary>
        /// Writes the child nodes from address.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <param name="writer">The writer.</param>
        /// <param name="bw">The background worker.</param>
        /// <param name="range">The range.</param>
        /// <param name="writeRoot">if set to <c>true</c> [write root].</param>
        void WriteChildNodesFromAddress(int[] address, XmlWriter writer, BackgroundWorker bw, IEnumerable<int> range, bool writeRoot = false);
        #endregion
    }
}